#ifndef _lcthw_BSTree_h
#define _lcthw_BSTree_h

typedef int (*BSTree_compare)(void *a, void *b); // Function pointer type

// BSTreeNode is a node in the binary search tree
// It contains a key, data, left, right, and parent pointers
// The key is used to compare nodes in the tree
// The data is the value stored in the node
// The left and right pointers point to the left and right children of the node
// The parent pointer points to the parent of the node
typedef struct BSTreeNode
{
    void *key;
    void *data;

    struct BSTreeNode *left;
    struct BSTreeNode *right;
    struct BSTreeNode *parent;
} BSTreeNode;

// The BSTree struct contains a count of the number of nodes in the tree
// It also contains a compare function pointer that is used to compare keys in the tree
// The root pointer points to the root node of the tree
typedef struct BSTree
{
    int count;
    BSTree_compare compare;
    BSTreeNode *root;
} BSTree;

// BSTree_traverse_cb is a function pointer type that is used to traverse the tree
// It takes a BSTreeNode pointer as an argument and returns an integer
typedef int (*BSTree_traverse_cb)(BSTreeNode *node);

// BSTree_create creates a new BSTree
// It takes a compare function pointer as an argument
// It returns a pointer to the new BSTree
BSTree *BSTree_create(BSTree_compare compare);

// BSTree_destroy destroys a BSTree
// It takes a pointer to the BSTree as an argument
void BSTree_destroy(BSTree *map);

// BSTree_set sets a key-value pair in the BSTree
// It takes a pointer to the BSTree, a key, and a value as arguments
// It returns 0 on success, -1 on failure
int BSTree_set(BSTree *map, void *key, void *data);

// BSTree_get gets the value associated with a key in the BSTree
// It takes a pointer to the BSTree and a key as arguments
// It returns a pointer to the value associated with the key
void *BSTree_get(BSTree *map, void *key);

// BSTree_delete deletes a key-value pair from the BSTree
// It takes a pointer to the BSTree and a key as arguments
// It returns the value associated with the key
void *BSTree_delete(BSTree *map, void *key);

// BSTree_traverse traverses the BSTree
// It takes a pointer to the BSTree and a traverse callback function pointer as arguments
// It returns 0 on success, -1 on failure
int BSTree_traverse(BSTree *map, BSTree_traverse_cb traverse_cb);

#endif